package com.pearlsoft.rms;

import java.util.List;
import java.util.Map;
import java.util.logging.Level;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.pearlsoft.webapp.sysmgr.cache.CacheService;
import com.pearlsoft.webapp.sysmgr.cache.Caches;
import com.vmware.vcloud.sdk.OrgNetwork;
import com.vmware.vcloud.sdk.Organization;
import com.vmware.vcloud.sdk.VCloudException;
import com.vmware.vcloud.sdk.VM;
import com.vmware.vcloud.sdk.Vapp;
import com.vmware.vcloud.sdk.Vdc;
import com.vmware.vcloud.sdk.admin.AdminOrganization;
import com.vmware.vcloud.sdk.admin.AdminVdc;

/**
 * 
 * @author rainshow
 * @Created 2012-6-8 下午12:30:58
 */

@Service("vcloudManager")
public class VcloudManagerCacheProxyImpl implements VcloudManager {

    @Resource(name = "cloudManager")
    private VcloudManager cloudManager;
    @Autowired
    private CacheService cacheService;

    @Override
    public String acquireTicket(String orgName, String vdcName, String appName, String vm) throws Exception {
        return cloudManager.acquireTicket(orgName, vdcName, appName, vm);
    }

    @Override
    public List<VM> createVapp(VappConfig config) {
        return cloudManager.createVapp(config);
    }

    @Override
    public Organization findOrgByName(String name) {
        return this.getOrgMap().get(name);
    }

    @Override
    public Vdc findVdc(String orgName, String vdcName) throws Exception {
        Vdc vdc = cacheService.get(Caches.VDC_CACHE, this.getVdcKey(orgName, vdcName));
        if (vdc == null) {
            vdc = cloudManager.findVdc(orgName, vdcName);
            cacheService.put(Caches.VDC_CACHE, this.getVdcKey(orgName, vdcName), vdc);
        }
        return vdc;
    }

    @Override
    public VM findVm(String orgName, String vdcName, String vappName, String vmName) throws Exception {
        return cloudManager.findVm(orgName, vdcName, vappName, vmName);
    }

    @Override
    public Map<String, AdminOrganization> getAdminOrgMap() {
        Map<String, AdminOrganization> map = cacheService.getAll(Caches.ADMIN_ORG_CACHE);
        if (map.isEmpty()) {
            map = cloudManager.getAdminOrgMap();
            cacheService.putAll(Caches.ADMIN_ORG_CACHE, map);
        }
        return map;
    }

    @Override
    public Map<String, AdminVdc> getAdminVdcMap(AdminOrganization org) {
        Map<String, AdminVdc> map = cacheService.get(Caches.ADMIN_VDC_CACHE, org.getResource().getId());
        if (map == null) {
            map = cloudManager.getAdminVdcMap(org);
            cacheService.put(Caches.ADMIN_VDC_CACHE, org.getResource().getId(), map);
        }
        return map;
    }

    @Override
    public Map<String, OrgNetwork> getNetworkMap(Organization org) {
        Map<String, OrgNetwork> map = cacheService.get(Caches.NETWORK_CACHE, org.getResource().getId());
        if (map == null) {
            map = cloudManager.getNetworkMap(org);
            cacheService.put(Caches.NETWORK_CACHE, org.getResource().getId(), map);
        }
        return map;
    }

    @Override
    public Map<String, Organization> getOrgMap() {
        Map<String, Organization> map = cacheService.getAll(Caches.ORG_CACHE);
        if (map.isEmpty()) {
            map = cloudManager.getOrgMap();
            cacheService.putAll(Caches.ORG_CACHE, map);
        }
        return map;
    }

    @Override
    public Map<String, Vapp> getVappMap(Vdc vdc) {
        return cloudManager.getVappMap(vdc);
    }

    @Override
    public Map<String, String> getVdcAvailableResource(String orgName, String vdcName) throws Exception {
        return this.getVdcAvailableResource(this.findVdc(orgName, vdcName));
    }

    public Map<String, String> getVdcAvailableResource(Vdc vdc) throws Exception {
        return cloudManager.getVdcAvailableResource(vdc);
    }

    @Override
    public Map<String, Vdc> getVdcMap(Organization org) {
        Map<String, Vdc> map = cacheService.get(Caches.VDC_CACHE, org.getResource().getId());
        if (map == null) {
            map = cloudManager.getVdcMap(org);
            cacheService.put(Caches.VDC_CACHE, org.getResource().getId(), map);
        }
        return map;
    }

    @Override
    public Map<String, String> getVdcResource(String orgName, String vdcName) throws Exception {
        return this.getVdcResource(this.findVdc(orgName, vdcName));
    }

    @Override
    public Map<String, String> getVdcResource(Vdc vdc) throws Exception {
        return cloudManager.getVdcResource(vdc);
    }

    @Override
    public List<VM> getVMList(Vapp app) {
        return cloudManager.getVMList(app);
    }

    @Override
    public String getVmPassword(String orgName, String vdcName, String vappName, String vmName) throws Exception {
        return cloudManager.getVmPassword(orgName, vdcName, vappName, vmName);
    }

    @Override
    public void setLogLevel(Level level) {
        cloudManager.setLogLevel(level);
    }

    @Override
    public boolean startVM(VM vm) throws VCloudException {
        return cloudManager.startVM(vm);
    }

    private String getVdcKey(String orgName, String vdcName) {
        return orgName + "." + vdcName;
    }

    public void cloneVapp(String orgName, String vdcName, String vappName, String targetOrg, String targetVdc,
            String baseline) throws Exception {
        cloudManager.cloneVapp(orgName, vdcName, vappName, targetOrg, targetVdc, baseline);
    }

    @Override
    public void updateVm(String orgName, String vdcName, String vappName, String vmName, int cpuNum, int memSize,
            int networkIncrement, int diskIncrement) throws Exception {
        cloudManager.updateVm(orgName, vdcName, vappName, vmName, cpuNum, memSize, networkIncrement, diskIncrement);
    }

    @Override
    public void closeVapp(Vapp vapp) throws Exception {
        cloudManager.closeVapp(vapp);
    }

    @Override
    public Vapp findVapp(String orgName, String vdcName, String vappName) throws Exception {
        return this.findVapp(this.findVdc(orgName, vdcName), vappName);
    }

    @Override
    public Vapp findVapp(Vdc vdc, String vappName) throws Exception {
        return cloudManager.findVapp(vdc, vappName);
    }

    @Override
    public void startVapp(Vapp vapp) throws Exception {
        cloudManager.startVapp(vapp);
    }

}
